package com.by.hashmap;

/**
 * @version 1.0
 * @Author 彭彦彬
 * @Date 2025/4/9 17:26
 * @注释
 */
import java.util.LinkedList;

public class MyHashMap<K, V> {
    private static final int DEFAULT_CAPACITY = 8; // 默认容量
    private static final double LOAD_FACTOR = 0.75; // 负载因子

    private LinkedList<Entry<K, V>>[] buckets; // 使用链表数组存储键值对
    private int size; // 当前存储的键值对数量
    private int capacity; // 当前容量

    public MyHashMap() {
        this(DEFAULT_CAPACITY);
    }

    @SuppressWarnings("unchecked")
    public MyHashMap(int capacity) {
        this.capacity = capacity;
        this.buckets = new LinkedList[capacity];
        for (int i = 0; i < capacity; i++) {
            buckets[i] = new LinkedList<>(); // 初始化每个桶为一个链表
        }
        this.size = 0;
    }

    /**
     * 插入键值对
     */
    public void put(K key, V value) {
        if ((double) size / capacity >= LOAD_FACTOR) {
            resize(); // 如果负载因子超过阈值，则扩容
        }

        int index = hash(key); // 计算哈希索引
        LinkedList<Entry<K, V>> bucket = buckets[index];

        // 检查是否已存在相同的 key，如果存在则更新 value
        for (Entry<K, V> entry : bucket) {
            if (entry.key.equals(key)) {
                entry.value = value;
                return;
            }
        }

        // 如果不存在相同的 key，则添加新的键值对
        bucket.add(new Entry<>(key, value));
        size++;
    }

    /**
     * 根据 key 获取对应的 value
     */
    public V get(K key) {
        int index = hash(key); // 计算哈希索引
        LinkedList<Entry<K, V>> bucket = buckets[index];

        for (Entry<K, V> entry : bucket) {
            if (entry.key.equals(key)) {
                return entry.value; // 找到 key，返回对应的 value
            }
        }

        return null; // 如果未找到，返回 null
    }

    /**
     * 删除指定 key 的键值对
     */
    public void remove(K key) {
        int index = hash(key); // 计算哈希索引
        LinkedList<Entry<K, V>> bucket = buckets[index];

        for (Entry<K, V> entry : bucket) {
            if (entry.key.equals(key)) {
                bucket.remove(entry); // 找到并移除键值对
                size--;
                return;
            }
        }
    }

    /**
     * 获取当前 HashMap 的大小
     */
    public int size() {
        return size;
    }

    /**
     * 判断 HashMap 是否为空
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 动态扩容
     */
    @SuppressWarnings("unchecked")
    private void resize() {
        capacity *= 2; // 容量翻倍
        LinkedList<Entry<K, V>>[] newBuckets = new LinkedList[capacity];
        for (int i = 0; i < capacity; i++) {
            newBuckets[i] = new LinkedList<>();
        }

        // 将旧的键值对重新分配到新的桶中
        for (LinkedList<Entry<K, V>> bucket : buckets) {
            for (Entry<K, V> entry : bucket) {
                int newIndex = hash(entry.key);
                newBuckets[newIndex].add(entry);
            }
        }

        buckets = newBuckets; // 更新桶数组
    }

    /**
     * 哈希函数：计算 key 的哈希值并映射到桶的索引
     */
    private int hash(K key) {
        return Math.abs(key.hashCode()) % capacity;
    }

    /**
     * 内部类：表示键值对
     */
    private static class Entry<K, V> {
        K key;
        V value;

        Entry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    public static void main(String[] args) {
        MyHashMap<String, Integer> map = new MyHashMap<>();
        map.put("A",23);
        map.put("B",24);
        map.put("C",26);
        System.out.println(map.get("A"));
        System.out.println(map.get("B"));
        System.out.println(map.get("C"));
    }
}
